﻿#include "stdafx.h"
#include "Ball_Ring.h"
#include "picture.h"


picture::picture()
{
	GetLocalTime(&tm_lo);   //获取当前时间
	sprintf_s(str, FILE_3); //写入字符串作为文件名
	_mkdir(str);			//创建文件夹
	TheredTrack = (640, 480, CV_32SC1, Scalar(255));
}


picture::~picture()
{
}

void picture::GetCap(Mat img, float scalingFactor)
{
	bool show = 0;
	SourceImg[ImgGetNum] = img.clone();
	if (!SourceImg[ImgGetNum].data)//是否为空
		while (1)
		{
			cout << "GetCap:cap is umpty     " << endl;
			Sleep(1000);
		}
	if (scalingFactor != 1) //不等于1就修改大小
		resize(SourceImg[ImgGetNum], SourceImg[ImgGetNum], Size(), scalingFactor, scalingFactor, INTER_AREA);
	cvtColor(SourceImg[ImgGetNum], GrayImg[ImgGetNum], CV_BGR2GRAY);//转化为灰度图
	if (show) {
		cout << ImgGetNum << endl;
		imshow("source", img);

	}
	ImgGetNum++;//更新帧数

}

void picture::SaveAll(int start, int end)
{

	bool show = 1;
	char StartImg1[100];
	strcpy_s(StartImg1, str);
	strcat_s(StartImg1, "\\开始帧.jpg");//开始帧
	Mat img;//缓存
	char EndImg[100];
	strcpy_s(EndImg, str);
	strcat_s(EndImg, "\\结束帧.jpg");//结束帧

	char GrayTrackName[100];
	strcpy_s(GrayTrackName, str);
	strcat_s(GrayTrackName, "\\GrayTrackImg.jpg");//轨迹灰度

	char TheredTrackName[100];
	strcpy_s(TheredTrackName, str);
	strcat_s(TheredTrackName, "\\BINImg.png");//轨迹二值

	char SourceName[100];
	strcpy_s(SourceName, str);
	strcat_s(SourceName, "\\Source.avi");//原视频

	char DiffName[100];
	strcpy_s(DiffName, str);
	strcat_s(DiffName, "\\Diff.avi");//差分视频


	VideoWriter SV(SourceName, CV_FOURCC('M', 'J', 'P', 'G'), 120, Size(SourceImg[0].cols, SourceImg[0].rows));//新建一个多媒体文件 

	//cout << SourceName << endl; 
	//system("pause");
	//	cout << "Saving......" << ImgGetNum << endl;
	for (int i = 0; i < end - 1; i++)
	{
		if (!SourceImg[i].data)
			cout << "SourceImg[i].data At save" << endl;
		img = SourceImg[i];
		SV << img;
		imshow("123", img);
		waitKey(1);

	}
//差分的结果还不会保存
//	VideoWriter DV(DiffName, CV_FOURCC('M', 'J', 'P', 'G'), 120, Size(640, 480));//新建一个多媒体文件 
	//for (int i = start; i < end - 3; i++)
	//{
	//	if (!DiffImg[i].data)
	//		cout << "DiffImg[i].data At save umpty" << endl;
	//	Mat img = DiffImg[i];
	//	DV << img;
	//}


	imwrite(EndImg, SourceImg[end - 1]);//记录开始帧
	imwrite(StartImg1, SourceImg[start - 1]);//记录结束帧
	imwrite(GrayTrackName, GrayTrack);//保存轨迹，灰度
	//imwrite(TheredTrackName, TheredTrack);//保存轨迹，二值,不正常
	cout << "Done. " << endl;
}

bool picture::Srart()
{


	return true;

}

Mat picture::draw(int start, int end) {
	bool show = 0;
	ImgDrawNum = start;//开始帧
	absdiff(DiffImg[start], DiffImg[start], GrayTrack);//获取同类型的空图片，希望能优化
	for (int i = start; i < end - 3; i++)
	{
		while (!DiffImg[ImgDrawNum].data)
			;//没数据就等着

		addWeighted(DiffImg[ImgDrawNum++], 1, GrayTrack, 1, 0, GrayTrack);//图片合并

		/*显示*/if (show) {
			imshow("GrayTrack", GrayTrack);
			//imshow("", );
			//imshow("ele_img", ele_img);
			//namedWindow("Frame");
			//createTrackbar("core", "Frame", &core, 30);
			//createTrackbar("yuz", "Frame", &yuz, 255);
			waitKey(1);
			/*移动*/if (1) {
				cvMoveWindow("input", 0, 0);
				cvMoveWindow("判断依据thered_img", 640, 0);
				cvMoveWindow("ele_img", 1280, 0);
				cvMoveWindow("", 0, 510);
				cvMoveWindow("Frame", 1280, 510);
				cvMoveWindow("", 640, 510);

			}
			/*销毁*/if (0) {
				//destroyWindow("判断依据thered_img");
				destroyWindow("ele_img");
				destroyWindow("thered_img");
				//destroyWindow("Frame");

			}
		}


	}
	return GrayTrack;
}

bool picture::diff(int start, int end)
{
	bool show = 0;
	static int core = 5;
	static int yuz = 24;
	static int yuz2 = 40;
	if (core < 1)core = 1;
	Mat  diffFrames1, diffFrames2;
	Mat Diff_or;
	Mat Difft_xor;
	Mat Diff_and;
	Mat Diff_threshod;//二值化
	Mat Diff_blur;//均值滤波图像
	Mat ball_ROI;
	if (!GrayImg[start].data)
		cout << "diff umpty!" << endl;
	for (int i = start; i < end - 2; i++)
	{
		absdiff(GrayImg[i + 2], GrayImg[i + 1], diffFrames1);//求差
		absdiff(GrayImg[i + 1], GrayImg[i], diffFrames2);
		bitwise_or(diffFrames1, diffFrames2, Diff_or);
		threshold(Diff_or, DiffImg[i], yuz2, 255, THRESH_TOZERO);//二值化,阈值尽量小，保留有用信息,可改成THRESH_BINARY辅助调试

															 //Mat element = getStructuringElement(MORPH_RECT, Size(thre + 1, thre + 1));//morphologyEx计算内核
															 //morphologyEx(Diff_img, Diff_img, MORPH_OPEN, element);
															 //morphologyEx(Diff_img, Diff_img, MORPH_CLOSE, element);//去燥1

															 //threshold(Diff_img, thre_img, yuz, 255, CV_THRESH_TOZERO);//去燥2，阈值化
															 //imshow("阈值化", thre_img);

		/*显示窗口*/if (show)
		{
			//	rectangle(Diff, Shuttlecock, Scalar(255));
			imshow("Diff_or", Diff_or);
			imshow("DiffImg[i]", DiffImg[i]);
			namedWindow("Frame");
			createTrackbar("core", "Frame", &core, 30);
			createTrackbar("yuz", "Frame", &yuz, 255);
			createTrackbar("yuz2", "Frame", &yuz2, 255);
			waitKey(1);
			/*移动窗口*/if (1) {
				cvMoveWindow("diffFrames1", 0, 0);
				cvMoveWindow("Diff_or", 640, 0);
				cvMoveWindow("Diff_blur", 1280, 0);
				cvMoveWindow("Diff_threshod", 0, 510);
				cvMoveWindow("Diff", 640, 510);
				cvMoveWindow("Frame", 1280, 510);

			}
			/*销毁窗口*/if (0) {

				destroyAllWindows();
			}
		}

	}
	return 0;
}
int picture::COUNT_Contous(Mat input, int min, int max, Ball_Ring fbr1)
{
	bool show = 1;
	double circle_Add = 0.3;
	static int core = 2;
	if (core < 1)core = 1;
	static int yuz = 58;
	Mat thered_img(input.rows, input.cols, CV_32SC1, Scalar(255));//二值化结果
	Mat ele_img;
	Mat element = getStructuringElement(MORPH_RECT, Size(core, core));//morphologyEx计算内核
	int Score = 0;//是否得分
	Point position;
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;
	Point2f center;
	float radius;
	if (input.data)
	{

		morphologyEx(input, ele_img, MORPH_OPEN, element);
		morphologyEx(ele_img, ele_img, MORPH_CLOSE, element);
		threshold(ele_img, thered_img, yuz, 255, CV_THRESH_BINARY);//去燥2，阈值化
		findContours(thered_img, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);	//找轮廓
		circle(thered_img, Point(fbr1.ring_x, fbr1.ring_y), fbr1.ring_r*(1 - 0.3), Scalar(100), 1, 8, 0);
		circle(thered_img, Point(fbr1.ring_x, fbr1.ring_y), fbr1.ring_r*(1 + 0.3), Scalar(100), 1, 8, 0);
		circle(thered_img, Point(fbr1.ring_x, fbr1.ring_y), fbr1.ring_r, Scalar(100), 1, 8, 0);

		for (int i = 0; i < contours.size(); i++)
		{
			int area = contourArea(contours[i]);//求轮廓面积大小
			if (area > 80)
			{
				minEnclosingCircle(Mat(contours[i]), center, radius);//求目标的最小外接圆
				float area_div = 3 * radius*radius / area;//求面积比
				int D_ = sqrt((center.x - fbr1.ring_x)*(center.x - fbr1.ring_x) + (center.y - fbr1.ring_y)*(center.y - fbr1.ring_y));//求目标与环的相对位置
				cout << area << endl;
				char str[100];
				sprintf_s(str, "_____%d,%1.1f", area, area_div);
				putText(thered_img, str, center, FONT_HERSHEY_SIMPLEX, 0.4, Scalar(100));
				if (area < max && area>min)					//面积合适？
				{
					if (D_<fbr1.ring_r*(1 + circle_Add) && D_>fbr1.ring_r*(1 - circle_Add))//目标在圆环附近
					{
						if (area_div < 4)	//面积比合适，即形状正常
						{
							Score++;
							circle(thered_img, center, radius, Scalar(150));
						}
					}

				}
			}
		}
		if (Score != 1)
			cout << "没进球,请调整参数" << endl;


		/*显示*/if (show) {
			//imshow("input", input);
			imshow("判断依据thered_img", thered_img);
			//	imshow("ele_img", ele_img);
			namedWindow("Frame");
			createTrackbar("core", "Frame", &core, 30);
			createTrackbar("yuz", "Frame", &yuz, 255);
			waitKey(1);
			/*移动*/if (1) {
				cvMoveWindow("input", 0, 0);
				cvMoveWindow("判断依据thered_img", 640, 0);
				cvMoveWindow("ele_img", 1280, 0);
				cvMoveWindow("", 0, 510);
				cvMoveWindow("Frame", 1280, 510);
				cvMoveWindow("", 640, 510);

			}
			/*销毁*/if (0) {
				//destroyWindow("判断依据thered_img");
				destroyWindow("ele_img");
				destroyWindow("thered_img");
				//destroyWindow("Frame");

			}
		}
		char TheredTrackName[100];
		strcpy_s(TheredTrackName, str);
		strcat_s(TheredTrackName, "\\BINImg.jpg");//轨迹二值

		imwrite(TheredTrackName, thered_img);
		cout << "D:\\判断依据.jpg已保存" << endl;
	}
	else cout << "COUNT_Contous is umpty!" << endl;
	return Score;
}

bool picture::Diff(Mat GrayImg, Mat DiffImg, Point ball, int r)
{
	bool show = 0;
	static int core = 5;
	static int yuz = 24;
	static int yuz2 = 30;
	if (core < 1)core = 1;
	Mat  diffFrames1, diffFrames2;
	Mat Diff_or;
	Mat Diff_blur;//均值滤波图像
	Mat ball_ROI;

	Mat output;



		bitwise_or(diffFrames1, diffFrames2, Diff_or);
		threshold(Diff_or, Diff_or, yuz2, 255, THRESH_TOZERO);//二值化,阈值尽量小，保留有用信息,可改成THRESH_BINARY辅助调试

	static Rect Ball_Rect;
	if (Ball_Rect.x)//不为零就更新
		Ball_Rect = Rect(ball.x, ball.y, r, r);

//	Rect Ball_Rect = Rect(RBE1.ball_x - RBE1.ball_r, RBE1.ball_y - RBE1.ball_r, 2 * RBE1.ball_r, 2 * RBE1.ball_r);//用矩形圈出球
	if (Ball_Rect.x +r > output.cols)
		Ball_Rect.x = output.cols - r;
	if (Ball_Rect.x - r< 0)
		Ball_Rect.x = r;
	if (Ball_Rect.y + Ball_Rect.height > output.rows)
	{
		static int count = 0;
		if (count++ > 3)Ball_Rect = Rect(0, 0, 0, 0);
		Ball_Rect.y = output.rows - Ball_Rect.height;
	}
	if (Ball_Rect.y < 0)
		Ball_Rect.y = 0;
	threshold(Diff_or(Ball_Rect), ball_ROI, yuz2, 255, THRESH_TOZERO);//二值化,阈值尽量小，保留有用信息,可改成THRESH_BINARY辅助调试
	rectangle(Diff_or, Ball_Rect, Scalar(255));

	//Mat element = getStructuringElement(MORPH_RECT, Size(thre + 1, thre + 1));//morphologyEx计算内核
	//morphologyEx(Diff_img, Diff_img, MORPH_OPEN, element);
	//morphologyEx(Diff_img, Diff_img, MORPH_CLOSE, element);//去燥1

	//threshold(Diff_img, thre_img, yuz, 255, CV_THRESH_TOZERO);//去燥2，阈值化
	//imshow("阈值化", thre_img);

	ball_ROI.copyTo(output(Ball_Rect));

	imshow("output", output);

	/*显示窗口*/if (show) {
		//	rectangle(Diff, Shuttlecock, Scalar(255));
		imshow("Diff_or", Diff_or);
		waitKey(1);

		namedWindow("Frame");
		createTrackbar("core", "Frame", &core, 30);
		createTrackbar("yuz", "Frame", &yuz, 255);
		createTrackbar("yuz2", "Frame", &yuz2, 255);

		/*移动窗口*/if (1) {
			cvMoveWindow("diffFrames1", 0, 0);
			cvMoveWindow("Diff_or", 640, 0);
			cvMoveWindow("Diff_blur", 1280, 0);
			cvMoveWindow("Diff_threshod", 0, 510);
			cvMoveWindow("Diff", 640, 510);
			cvMoveWindow("Frame", 1280, 510);

		}
		/*销毁窗口*/if (0) {

			destroyAllWindows();
		}
	}

	return false;
}


